package com.hds.modules.app.controller;

import com.hds.common.utils.HttpUtils;
import com.hds.common.utils.R;
import com.hds.common.validator.Assert;
import com.hds.modules.app.annotation.Login;
import com.hds.modules.app.annotation.LoginUser;
import com.hds.modules.app.entity.ActivationCodeEntity;
import com.hds.modules.app.entity.UserEntity;
import com.hds.modules.app.enums.ActivateCode;
import com.hds.modules.app.enums.UserEnum;
import com.hds.modules.app.form.LoginForm;
import com.hds.modules.app.service.ActivationCodeService;
import com.hds.modules.app.service.UserService;
import com.hds.modules.app.utils.DateUtils;
import com.hds.modules.app.utils.HdsUtils;
import com.hds.modules.app.utils.JwtUtils;
import com.hds.modules.job.entity.ScheduleJobEntity;
import com.hds.modules.job.service.ScheduleJobService;
import com.hds.modules.sys.controller.AbstractController;
import com.hds.modules.sys.entity.base.SysMemberShipEntity;
import com.hds.modules.sys.service.base.SysCompanyService;
import com.hds.modules.sys.service.base.SysMemberShipService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.*;

/**
 * @Author guonan
 * @Email guonan@yewcn.com
 * @Description
 * @Date 2018/6/11 11:49
 */
@RestController
@RequestMapping("/app/activatecode")
public class AppActivationCodeController extends AbstractController{
    @Autowired
    private ActivationCodeService activationCodeService;

    @Autowired
    private UserService userService;

    @Autowired
    private SysMemberShipService sysMemberShipService;

    @Autowired
    private ScheduleJobService scheduleJobService;

    @Autowired
    private SysCompanyService sysCompanyService;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private HdsUtils hdsUtils;

    public static final String relationGt = "gt"; //大于
    public static final String relationEq = "eq"; //等于


    /**
     * 激活
     * @param
     * @param code
     * @return
     */
    @Transactional
    @Login
    @GetMapping("/activate")
    public R activate(@LoginUser UserEntity user, @RequestParam(value = "code", required = false) String code, String mobile){
        Assert.isNull(code,"激活码不能为空");
        code = code.toUpperCase();

        /**
         * 临时代码，后面会拿掉
         */
        long userId = user.getUserId();
        //登录
      /*  LoginForm form = new LoginForm();
        form.setMobile(mobile);
        //用户登录
        long userId = userService.login(form);
        String token = jwtUtils.generateToken(userId);
        logger.info(">>>>userId:{}", userId);
        UserEntity user = userService.selectById(userId);
        if(user==null)return R.error("该用户未找到");

        logger.info(">>>>code:{}", code);*/







        ActivationCodeEntity activationCode = activationCodeService.queryByCode(code);
        Assert.isNull(activationCode,"该激活码不存在");
        Integer status = activationCode.getStatus();
        //查询当前登录用户的最高等级
        //Integer userLevelId = null;
        //Integer userLevelId = 5;

        if(ActivateCode.StatusEnum.ACTIVATED.getStatus() == status){
            return R.error("该激活码已激活");
        }
        if(ActivateCode.StatusEnum.EXPIRED.getStatus() == status){
            return R.error("该激活码已失效");
        }

        //UserEntity user = userService.selectById(userId);
        Integer userLevelId = user.getLevelId();
        Integer userLevel = null;
        Integer codeLevel = null;
        boolean rst = false;
        Date expireDate=null;

        if(userLevelId!=null){
            SysMemberShipEntity codeLevelShip = sysMemberShipService.selectById(activationCode.getLevelId());
            SysMemberShipEntity ship = sysMemberShipService.selectById(userLevelId);
            if(ship==null){
                return R.error("未找到该用户对应的用户等级");
            }
            userLevel = ship.getLevel(); // 当前用户等级
            String levelImg = codeLevelShip.getImg();
            codeLevel = codeLevelShip.getLevel(); // 当前要激活的激活码等级
            //当前激活码所属公司
            String companyName = sysCompanyService.selectById(activationCode.getCompanyId()).getName();
            //当前激活码所属等级
            String levelName = sysMemberShipService.selectById(activationCode.getLevelId()).getName();


            if(userLevel == UserEnum.VipLevel.TOURIST.getLevel()){
                rst = activate(activationCode, userId); //游客升级成[vip会员卡、金卡]
                if(rst){
                    expireDate = activationCode.getExpireTime();
                    System.out.println("expireDate=="+expireDate);
                }else{
                    return R.error("激活失败，请联系管理员");
                }

            }else{
                Map<String, Object> map = new HashMap<>();
                map.put("uid", userId);
                map.put("status", ActivateCode.StatusEnum.ACTIVATED.getStatus());
                map.put("company_id", activationCode.getCompanyId());
                List<ActivationCodeEntity> list = activationCodeService.selectByMap(map);
                String relation = null;
                if(codeLevel > userLevel){
                    // 等级覆盖
                    rst = activate(activationCode, userId);
                    if(rst){
                        expireDate = updateCurrCode(list, activationCode, relationGt);
                    }
                }
                if(codeLevel == userLevel){
                    // 等级累加
                    rst = activate(activationCode, userId);
                    if(rst){
                        expireDate = updateCurrCode(list, activationCode, relationEq);
                    }
                }
                if(codeLevel < userLevel){
                    return R.error("该激活码的等级低于当前用户等级，不能激活该激活码");
                }
            }

            // 生成激活码定时器，过期后更新该激活码状态，并且将该用户的等级设置为游客
            if(rst){
                //将该用户之前的所有激活码定时器job设置为暂停状态
                Map<String, Object> codeMap = new HashMap<>();
                codeMap.put("uid",userId);
                List<ActivationCodeEntity> codeList = activationCodeService.selectByMap(codeMap);
                System.out.println("codeList==="+codeList.size());
                for (ActivationCodeEntity actCode: codeList) {
                    System.out.println("actCode==="+actCode);
                    if(actCode!=null){
                        ScheduleJobEntity job = scheduleJobService.queryByParam(String.valueOf(actCode.getId()));
                        System.out.println("job==="+job);
                        if(job!=null){
                            job.setStatus(1); //暂停状态
                            scheduleJobService.updateById(job);
                        }
                    }
                }


                //创建定时器，过了保质期后该公司的这一批未激活的激活码全部失效 [要考虑到保质期内已经激活的激活码]
                //生成定时器 - [激活码超过保质期失效]
                generateJob(expireDate,"activateCodeTask",
                        "activateExpire",
                        String.valueOf(activationCode.getId()),
                        "该激活码(code:"+activationCode.getActivationcode()+")已激活");


                //return R.ok().desc("激活成功").put("company",companyName).put("level",levelName);
                return R.ok().desc("激活成功")
                        .put("company",companyName)
                        .put("level",levelName)
                        .put("img", levelImg)
                        .put("vipLevel", codeLevel);
            }

        }
        return R.error();

    }


    /**
     * 生成定时器：激活码过期失效
     * @param date 过期时间
     * @param taskName
     * @param methodName
     * @param params
     * @param mark
     */
    public void generateJob(Date date, String taskName, String methodName, String params, String mark){
        String expiredYear = DateUtils.format(date, "yyyy");
        String expiredTimeFormat = DateUtils.format(date, "ss mm HH dd MM");
        String cron = expiredTimeFormat+" ? "+expiredYear;
        logger.info("激活码过期cron表达式：{}", cron);
//        String cron = "0 */10 * * * ?";
        //创建定时器，过了保质期后该公司的这一批未激活的激活码全部失效 [要考虑到保质期内已经激活的激活码]
        ScheduleJobEntity scheduleJob = new ScheduleJobEntity();
        scheduleJob.setBeanName(taskName);
        scheduleJob.setCreateTime(new Date());
        scheduleJob.setCronExpression(cron); //cron表达式 例如:30 10 1 20 10 ? 2011
        scheduleJob.setMethodName(methodName);
        scheduleJob.setParams(params);
        scheduleJob.setRemark(mark); //"该公司(id:"+companyId+")第"+nextBatch+"批次激活码更新为过期状态-标记"
        scheduleJob.setStatus(0);

        //生成定时器
        scheduleJobService.save(scheduleJob);
    }





    /**
     * 将之前已激活的激活码设置失效,
     * eq:过期时间累加
     * gt:过期时间等级覆盖[过期时间按照该激活码的过期时间按算，不累加]
     * @param list
     * @param activationCode
     * @param relation
     * @return 返回过期时间
     */
    public Date updateCurrCode(List<ActivationCodeEntity> list, ActivationCodeEntity activationCode, String relation){
        boolean rst = false;
        Date expireDate = null;
        if(list!=null && list.size()>0){
            //将之前已激活的激活码设置失效
            boolean b = setExpiredForAllCode(list);
            if(b){
                switch (relation){
                    case relationGt:
                        //过期时间等级覆盖[过期时间按照该激活码的过期时间按算，不累加]
                        expireDate = DateUtils.addYear(activationCode.getPeriod());
                        activationCode.setExpireTime(expireDate);
                        break;
                    case relationEq:
                        //过期时间累加
                        expireDate = DateUtils.addYear(list.get(0).getExpireTime(), activationCode.getPeriod());
                        activationCode.setExpireTime(expireDate);
                        break;
                }

                activationCode.setStatus(ActivateCode.StatusEnum.ACTIVATED.getStatus());
                rst = activationCodeService.insertOrUpdate(activationCode);
                if(rst)return expireDate;
            }
        }
        return null;
    }


    public boolean setExpiredForAllCode(List<ActivationCodeEntity> list){
        for (ActivationCodeEntity code : list) {
            System.out.println("===code:"+code.getActivationcode()+"===="+code.getId());
            code.setStatus(ActivateCode.StatusEnum.EXPIRED.getStatus());
        }
        return activationCodeService.updateBatchById(list);
    }


    public boolean activate(ActivationCodeEntity activationCode, Long userId){
        Integer period = activationCode.getPeriod();
        Date currDate = new Date(); //当前时间
        Date expireTime = DateUtils.addYear(period); //当前时间+年

        activationCode.setStatus(ActivateCode.StatusEnum.ACTIVATED.getStatus());
        activationCode.setActivateTime(currDate);
        activationCode.setUid(Integer.valueOf(String.valueOf(userId)));
        activationCode.setExpireTime(expireTime);
        boolean b = activationCodeService.insertOrUpdate(activationCode);

        //激活成功，更新用户等级
        UserEntity user = userService.selectById(userId);
        if(b && user!=null) {
            user.setLevelId(activationCode.getLevelId());
            boolean UpdRst = userService.insertOrUpdate(user);
            return UpdRst;
        }

        return false;
    }


}
